var isLoad = false;
var st;
var Log = {
    elem: false,
    write: function(text, icon) {
        if (!this.elem) {
            this.elem = Ext.get('log');
        }
        if (icon == 0) {
            this.elem.removeClass('loading-tree');
        } else {
            this.elem.addClass('loading-tree');
        }
        this.elem.update(text);
    }
};

function searchNode () {
    var id = Ext.fly('search-node').getValue();

    if (!id) {
        alert('Please enter member id');
        Ext.fly('search-node').highlight().focus();
        return;
    }

    if (Ext.fly('mycanvas')) {
        Log.write('Remove existing tree..', 1);

        st.removeSubtree(st.json.id, true, 'animate');
        setTimeout(loadSubtree, 500);

        /*Ext.fly('mycanvas').fadeOut({
            remove: true,
            callback: function(){
                init();
            }
        });*/
    } else {
        init();
    }
} // searchNode

function displayData (name, data) {
    Ext.fly('fullname').highlight('0000ff', {
        attr: 'color',
        duration: 2
    }).update(name);

    Ext.each(Ext.query('td.val, td.val2, span.val', 'details'), function(e){
        eval('var val = data.'+e.id);
        blk = (e.className == 'val') ? '-' : '0';
        val = (typeof(val) == 'undefined') ? blk : val;
        Ext.fly(e.id).highlight('0000ff', {
            attr: 'color',
            duration: 2
        }).update(val);
    });
} // displayData

function loadSubtree () {
    transId = Ext.Ajax.request({
        url: _webroot+'/members/genealogy',
        params: 'id='+Ext.fly('search-node').getValue()+'&levelsToShow=2&init=1',
        method: 'POST',
        success: function(response, opts) {
            setTimeout(checkResult, 2000);

            var obj = Ext.decode(response.responseText);

            if (obj.status == true) {
                if (!Ext.fly('details').isVisible()) {
                    Ext.fly('details').slideIn('t', {
                        easing: 'easeOut'
                    });
                }

                st.loadJSON(obj.data);
                st.compute();
                st.onClick(st.root);
                displayData(obj.data.name, obj.data.data);
            }
        },
        failure: function(response, opts) {
            message('server-side failure with status code '+response.status);
        },
        callback: function() {
            isLoad = false;
            Log.write('Tree loaded', 0);
        }
    });

    if (Ext.Ajax.isLoading(transId)) {
        isLoad = true;
        Log.write('Initial tree..', 1);
    }
} // loadSubtree

function addEvent (obj, type, fn) {
    if (obj.addEventListener) obj.addEventListener(type, fn, false);
    else obj.attachEvent('on' + type, fn);
};


function init () {
    var canvas = new Canvas('mycanvas', {
        'injectInto': 'infovis',
        'width': 800,
        'height': 500,
        'backgroundColor': '#BFCED9',
        'styles': {
           'fillStyle': '#ccddee',
           'strokeStyle': '#772277'
        }
    });

    st = null;
    // Implement a node rendering function called 'nodeline' that plots a straight line when contracting or expanding a subtree.
    ST.Plot.NodeTypes.implement({
        'nodeline': function(node, canvas, animating) {
            if(animating === 'expand' || animating === 'contract') {
                var pos = node.pos.getc(true), nconfig = this.node, data = node.data;
                var width  = nconfig.width, height = nconfig.height;
                var algnPos = this.getAlignedPos(pos, width, height);
                var ctx = canvas.getCtx(), ort = this.config.orientation;
                ctx.beginPath();
                if(ort == 'left' || ort == 'right') {
                    ctx.moveTo(algnPos.x, algnPos.y + height / 2);
                    ctx.lineTo(algnPos.x + width, algnPos.y + height / 2);
                } else {
                    ctx.moveTo(algnPos.x + width / 2, algnPos.y);
                    ctx.lineTo(algnPos.x + width / 2, algnPos.y + height);
                }
                ctx.stroke();
            }
        }
    });

    // Create a new ST instance
    st = new ST(canvas, {
        orientation: 'top',
        duration: 800,                      //set duration for the animation
        transition: Trans.Quart.easeInOut,  //set animation transition type
        levelDistance: 30,                  //set distance between node and its children
        levelsToShow: 2,                    //set max levels to show. Useful when used with the request method for requesting trees of specific depth
        withLabels: true,
        Node: {
            width: 188,
            height: 45,
            lineWidth: 2,
            align: 'center',
            overridable: true
        },
        Edge: {
            type: 'bezier',
            lineWidth: 2,
            overridable: true
        },
        request: function(nodeId, level, onComplete) {
            if (isLoad) {
                return;
            }

    transId = Ext.Ajax.request({
        url: _webroot+'/members/genealogy',
        params: 'id='+nodeId+'&levelsToShow='+level,
        method: 'POST',
        success: function(response, opts) {
            setTimeout(checkResult, 2000);

            var obj = Ext.decode(response.responseText);

            if (obj.status == true) {
                onComplete.onComplete(nodeId, obj.data);
            }
        },
        failure: function(response, opts) {
            message('server-side failure with status code '+response.status);
        },
        callback: function() {
            isLoad = false;
            Log.write('Load completed', 0);
        }
    });

    if (Ext.Ajax.isLoading(transId)) {
        isLoad = true;
    }
        },
        onBeforeCompute: function(node){
            Log.write('Loading downline of '+node.name, 1);
        },
        onAfterCompute: function(){
            Log.write('Done', 0);
        },
        onCreateLabel: function(label, node){
//console.log(node.id+'/'+node.data.i_id);
            label.id        = node.id;
            label.innerHTML = node.name+'<div>'+node.data.i_id+'</div>';
            label.onclick   = function(){
                if (isLoad) {
                    alert('Please wait while sub tree is loading..');
                } else {
                    st.onClick(node.id);
                }
                displayData(node.name, node.data);
            };

            var style = label.style;
            style.width          = 188+'px';
            style.height         = 55+'px';
            style.fontSize       = '0.8em';
            style.paddingTop     = '13px';
            style.cursor         = 'pointer';
            style.textAlign      = 'center';
            style.textDecoration = 'none';

            if (node.name == 'Reserved') {
                style.paddingbottom = '0px';
                style.color         = '#333';
                style.fontStyle     = 'italic';
            } else {
                style.color = '#21759B';
            }
        },
        onBeforePlotNode: function(node){
            if (node.selected) {
                node.data.$color = "#BFCED9";
            } else {
                delete node.data.$color;
            }
        },
        onBeforePlotLine: function(adj){
            if (adj.nodeFrom.selected && adj.nodeTo.selected) {
                adj.data.$color = "#333";
                adj.data.$lineWidth = 3;
            } else {
                delete adj.data.$color;
                delete adj.data.$lineWidth;
            }
        }
    });

    loadSubtree();
} // init

function checkResult () {
    if (isLoad) {
        isLoad = false;
        Log.write('<span class="red">Fail loading downline at this time, please try again.</span>', 0);
    }
} // checkResult